package com.hxzy.controller.system;

import com.hxzy.common.annotation.Log;
import com.hxzy.common.constant.UserConstants;
import com.hxzy.common.core.controller.BaseController;
import com.hxzy.common.core.domain.R;
import com.hxzy.common.core.domain.TreeSelect;
import com.hxzy.common.core.domain.entity.SysMenu;
import com.hxzy.common.core.domain.model.LoginUser;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.enums.BusinessType;
import com.hxzy.common.utils.SecurityUtils;
import com.hxzy.common.utils.StringUtils;
import com.hxzy.system.domain.dto.SysMenuSearchDTO;
import com.hxzy.system.domain.dto.ValueExistsDTO;
import com.hxzy.system.service.ISysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/api")
@Api(tags = "菜单API")
public class SysMenuController extends BaseController {

    @Autowired
    private ISysMenuService sysMenuService;

    @PreAuthorize("@hxzy.hasPermi('system:menu:list')")
    @ApiOperation(value = "根据条件查询菜单")
    @GetMapping(value = "/system/menu/list")
    public R search(SysMenuSearchDTO sysMenuSearchDTO){
        List<SysMenu> sysMenuList = this.sysMenuService.selectMenuList(sysMenuSearchDTO);
        return R.okHasData(sysMenuList);
    }


    @ApiOperation(value = "加载树型菜单数据")
    @GetMapping(value = "/system/menu/treeselect")
    public R menuTreeSelect(){
        //根据条件查询菜单，这里没有给对象赋值，相当于全查询
        List<SysMenu> menus = sysMenuService.selectMenuList(new SysMenuSearchDTO());
        //把SysMenu转换成树型节点
        List<TreeSelect> treeSelects=this.sysMenuService.buildMenuTreeSelect(menus);
        return R.okHasData(treeSelects);
    }

    @ApiOperation(value = "加载对应角色菜单列表树")
    @GetMapping(value = "/system/menu/roleMenuTreeselect/{roleId}")
    public R roleMenuTreeselect(@PathVariable("roleId") Long roleId)
    {
        //根据条件查询菜单，这里没有给对象赋值，相当于全查询
        List<SysMenu> menus = sysMenuService.selectMenuList(new SysMenuSearchDTO());

        //根据该角色id拥有的菜单
        List<Long> checkMenu=  this.sysMenuService.selectMenuListByRoleId(roleId);

        //把SysMenu转换成树型节点
        List<TreeSelect> treeSelects=this.sysMenuService.buildMenuTreeSelect(menus);

        //组装数据到前端
        Map<String,Object> data=new HashMap<>();
        data.put("checkedKeys", checkMenu);
        data.put("menus", treeSelects);

        return R.okHasData(data);
    }

    /**
     * 根据菜单编号获取详细信息
     */
    @PreAuthorize("@hxzy.hasPermi('system:menu:query')")
    @GetMapping(value = "/system/menu/{menuId}")
    public R getInfo(@PathVariable Long menuId)
    {
        return R.okHasData(this.sysMenuService.selectMenuById(menuId));
    }

    /**
     * 新增菜单
     */
    @PreAuthorize("@hxzy.hasPermi('system:menu:add')")
    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
    @PostMapping(value = "/system/menu")
    public R add(@Validated @RequestBody SysMenu menu)
    {
        if (UserConstants.NOT_UNIQUE.equals(this.sysMenuService.checkMenuNameUnique(new ValueExistsDTO(null,menu.getMenuName()))))
        {
            R r=R.build(AckCode.FAIL);
            r.setMsg("新增菜单'" + menu.getMenuName() + "'失败，菜单名称已存在");
            return r;
        }
        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
        {
            R r=R.build(AckCode.FAIL);
            r.setMsg("新增菜单'" + menu.getMenuName() + "'失败，地址必须以http(s)://开头");
            return r;
        }

        return super.toAjax(this.sysMenuService.save(menu));
    }

    /**
     * 修改菜单
     */
    @PreAuthorize("@hxzy.hasPermi('system:menu:edit')")
    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
    @PutMapping(value = "/system/menu")
    public R edit(@Validated @RequestBody SysMenu menu)
    {

        if (UserConstants.NOT_UNIQUE.equals(this.sysMenuService.checkMenuNameUnique(new ValueExistsDTO(menu.getMenuId(),menu.getMenuName()))))
        {
            R r=R.build(AckCode.FAIL);
            r.setMsg("修改菜单'" + menu.getMenuName() + "'失败，菜单名称已存在");
            return r;
        }
        else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
        {
            R r=R.build(AckCode.FAIL);
            r.setMsg("修改菜单'" + menu.getMenuName() + "'失败，地址必须以http(s)://开头");
            return r;
        }
        else if (menu.getMenuId().equals(menu.getParentId()))
        {
            R r=R.build(AckCode.FAIL);
            r.setMsg("修改菜单'" + menu.getMenuName() + "'失败，上级菜单不能选择自己");
            return r;
        }

        return toAjax(this.sysMenuService.updateById(menu));
    }

    /**
     * 删除菜单
     */
    @PreAuthorize("@hxzy.hasPermi('system:menu:remove')")
    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/system/menu/{menuId}")
    public R remove(@PathVariable("menuId") Long menuId)
    {
        if (this.sysMenuService.hasChildByMenuId(menuId))
        {
            R r=R.build(AckCode.FAIL);
            r.setMsg("存在子菜单,不允许删除");
            return r;
        }
        if (this.sysMenuService.checkMenuExistRole(menuId))
        {
            R r=R.build(AckCode.FAIL);
            r.setMsg("菜单已分配,不允许删除");
            return r;
        }
        return toAjax(this.sysMenuService.removeById(menuId));
    }

}
